package net.blank.customMousePointer
{
	import net.blank.bitmapOperation.BitmapDraw;
	
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;
	
	/**
	 * 自定义鼠标指针
	 * @author blank
	 * 
	 */
	public class CustomMousePointer
	{
		/**静态实例*/
		private static var $instance:CustomMousePointer;
		
		/**鼠标指针*/
		protected var $mouserPointer:Shape;
		
		/**舞台对象*/
		private var $stageObj:Stage;
		
		/**鼠标指针列表*/
		protected var _mousePointers:Vector.<BitmapData>;
		
		/**鼠标是否已被按下*/
		private var isDown:Boolean;
		
		/**默认鼠标指针集合*/
		protected var defaultMousePointers:MousePointerInfo;
		
		/**当前鼠标指针集合*/
		protected var curMousePointers:MousePointerInfo;
		
		/**鼠标指针的目标*/
		protected var mouseTargets:Vector.<Sprite>;
		
		/**鼠标指针集合*/
		protected var mousePointerses:Vector.<MousePointerInfo>;
		
		/**
		 * 添加鼠标指针改变的目标
		 * @param target
		 * @param normalPointerId
		 * @param downPointerId
		 * @param linkPointerId
		 * @param linkDownPointerId
		 * @param disabledPointerId
		 * 
		 */
		public function addMouseTarget(
			target:Sprite,
			normalPointerId:uint=0,
			downPointerId:uint=1,
			linkPointerId:uint=0,
			linkDownPointerId:uint=1,
			disabledPointerId:uint=0
		):void{
			mouseTargets.push(target);
			
			var newMd:MousePointerInfo=new MousePointerInfo();
			newMd.normalPointerId=normalPointerId;
			newMd.downPointerId=downPointerId;
			newMd.linkPointerId=linkPointerId;
			newMd.linkDownPointerId=linkDownPointerId;
			newMd.disabledPointerId=disabledPointerId;
			
			mousePointerses.push(newMd);
		}
		
		/**
		 * 移除鼠标指针的目标
		 * @param target
		 * 
		 */
		public function rmMouseTarget(target:Sprite):void{
			var index:int=mouseTargets.indexOf(target);
			if(index != -1){
				mouseTargets.splice(index,1);
				mousePointerses.splice(index,1);
			}
		}
		
		/**绘制鼠标指针*/
		private function drawMousePointer(pointerId:uint=0):void{
			if(pointerId < _mousePointers.length){
				$mouserPointer.graphics.clear();
				BitmapDraw.drawBitmap($mouserPointer.graphics,_mousePointers[pointerId]);
			}
		}
		
		/**绘制鼠标根据其所在位置*/
		private function draw(target:Sprite=null):void{
			if(target){
				if(target.hasEventListener("enabled")){
					if(!target["enabled"]){
						drawMousePointer(curMousePointers.disabledPointerId);
						return;
					}
				}
				if(target.buttonMode){
					if(isDown){
						drawMousePointer(curMousePointers.linkDownPointerId);
					}else{
						drawMousePointer(curMousePointers.linkPointerId);
					}
					return;
				}
			}
			if(isDown){
				drawMousePointer(curMousePointers.downPointerId);
			}else{
				drawMousePointer(curMousePointers.normalPointerId);
			}
		}
		
		/**鼠标移动*/
		private function mouseMove(evt:MouseEvent):void{
			$mouserPointer.x=$stageObj.mouseX;
			$mouserPointer.y=$stageObj.mouseY;
			
			$stageObj.setChildIndex($mouserPointer,$stageObj.numChildren-1);
			
			evt.updateAfterEvent();
		}
		
		/**鼠标按下*/
		private function mouseDown(evt:MouseEvent):void{
			isDown=true;
			draw(evt.target as Sprite);
		}
		
		/**鼠标释放*/
		private function mouseUp(evt:MouseEvent):void{
			isDown=false;
			draw(evt.target as Sprite);
		}
		
		/**鼠标进入*/
		private function mouseOver(evt:MouseEvent):void{
			var target:*=evt.target;
			
			if(target is Sprite){
				var index:int;
				while(target.parent != null){
					index=mouseTargets.indexOf(target);
					if(index != -1){
						curMousePointers=mousePointerses[index];
						draw(target);
						break;
					}
					target=target.parent;
				}
			}
		}
		
		/**鼠标移出*/
		private function mouseOut(evt:MouseEvent):void{
			curMousePointers=defaultMousePointers;
			draw();
		}
		
		/**显示鼠标指针(隐藏系统鼠标指针,显示自定义鼠标指针)*/
		public function show(stage:Stage=null):void{
			Mouse.hide();
			
			if(stage && $stageObj != stage){
				if($stageObj){
					rmListener();
				}
				
				$stageObj=stage;
				
				regListener();
			}
			
			if($stageObj){
				$stageObj.addChild($mouserPointer);
			}
			
			$mouserPointer.visible=true;
		}
		
		/**隐藏鼠标指针(隐藏自定义鼠标指针,显示系统鼠标指针)*/
		public function hide(systemMouseVisible:Boolean=true):void{
			$mouserPointer.visible=false;
			
			if(systemMouseVisible){
				Mouse.show();
			}
		}
		
		/**注册事件侦听器*/
		private function regListener():void{
			$stageObj.addEventListener(MouseEvent.MOUSE_MOVE,mouseMove);
			$stageObj.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
			$stageObj.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
			$stageObj.addEventListener(MouseEvent.MOUSE_OVER,mouseOver);
			$stageObj.addEventListener(MouseEvent.MOUSE_OUT,mouseOut);
		}
		
		/**移除事件侦听器*/
		private function rmListener():void{
			$stageObj.removeEventListener(MouseEvent.MOUSE_MOVE,mouseMove);
			$stageObj.removeEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
			$stageObj.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
			$stageObj.removeEventListener(MouseEvent.MOUSE_OVER,mouseOver);
			$stageObj.removeEventListener(MouseEvent.MOUSE_OUT,mouseOut);
		}
		
		public function CustomMousePointer(){
			if(!$instance){
				$mouserPointer=new Shape();
				
				defaultMousePointers=new MousePointerInfo();
				curMousePointers=defaultMousePointers;
				
				mouseTargets=Vector.<Sprite>([]);
				mousePointerses=Vector.<MousePointerInfo>([]);
			}else{
				throw new Error("只能用getInstance()来获取实例!");
			}
		}
		
		/**鼠标指针列表*/
		public function set mousePointers(value:Vector.<BitmapData>):void{
			if(value != _mousePointers){
				_mousePointers=value;
			}
		}
		public function get mousePointers():Vector.<BitmapData>{
			return _mousePointers;
		}
		
		/**获取实例*/
		public static function getInstance():CustomMousePointer{
			if(!$instance){
				$instance=new CustomMousePointer();
			}
			return $instance;
		}
	}
}